﻿using Plexi.Tools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

namespace Plexi
{
	internal static class ExtensionMethods
	{
		internal static double GetLongitudeNormalized(this CelestialBody body, Vector3d worldPos)
		{
			return MathTools.NormalizeLongitude(body.GetLongitude(worldPos));
		}

		internal static CBAttributeMapSO.MapAttribute GetBiome(this CelestialBody body, double lat, double lon)
		{
			return body.BiomeMap.GetAtt(Mathf.Deg2Rad * lat, Mathf.Deg2Rad * MathTools.NormalizeLongitude(lon));
		}

		internal static int GetBiomeIndex(this CelestialBody body, CBAttributeMapSO.MapAttribute biome)
		{
			CBAttributeMapSO.MapAttribute a;
			for (int i = 0; i < body.BiomeMap.Attributes.Length; i++)
			{
				a = body.BiomeMap.Attributes[i];
				if (a.Equals(biome))
					return i;
			}
			return -1;
		}

		internal static string FindBiomeName(this CelestialBody body, int biomeIndex)
		{
			if (biomeIndex >= 0 && biomeIndex < body.BiomeMap.Attributes.Length)
				return body.BiomeMap.Attributes[biomeIndex].name;
			return "Unknown";
		}

		/// <summary>Finds the CelestialBody object with the given name. Case-insensitive. Returns null if not found.</summary>
		internal static CelestialBody FindByName(this List<CelestialBody> bodies, string bodyName)
		{
			bodyName = bodyName.ToLower();
			CelestialBody b;
			for (int i = 0; i < bodies.Count; i++)
			{
				b = bodies[i];
				if (b.bodyName.ToLower().Equals(bodyName))
					return b;
			}
			return null;
		}

		internal static bool IsInWater(this CelestialBody body, double lat, double lon)
		{
			return body.ocean && KspTools.GetElevation(body, lat, lon) <= 0.1f;
		}

		/// <summary> A workaround for when SetActive(false) does not deactivate the gameobject properly...</summary>
		internal static void SetActiveReally(this GameObject o, bool active)
		{
			o.SetActive(active);
			if (o.renderer != null)
				o.renderer.enabled = active;
			if (o.rigidbody != null)
				o.rigidbody.detectCollisions = active;
			if (o.collider != null)
				o.collider.enabled = active;

		}

		internal static bool IsSinglePartVessel(this Vessel vessel)
		{
			return vessel != null && !vessel.isEVA && vessel.Parts != null && vessel.Parts.Count == 1;
		}
	}
}
